<?php
class Encypt
{
	private $_authkey = '%s1*ba12';
	public function __construct()
	{
		$this->_authkey = Yii::app ()->params ['authkey'];
		// authkey = md5($_DCACHE['settings']['authkey'].$_SERVER['HTTP_USER_AGENT']);
	}
	/**
	 * 加密解密函数
	 * 待加密内容用\t分割
	 * example:
	 * list($discuz_pw, $discuz_secques, $discuz_uid) = empty($_DCOOKIE['auth']) ? array('', '', 0) : daddslashes(explode("\t", authcode($_DCOOKIE['auth'], 'DECODE')), 1);
	 * 
	 * @return String 加密或解密字符串
	 * @param String $string 待加密或解密字符串
	 * @param String $operation 操作类型定义 DECODE=解密 ENDODE=加密
	 * @param String $key 加密算子
	 */
	public static function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
	{
		$ckey_length = 4;
		
		$key = md5 ( $key ? $key : $this->_authkey );
		$keya = md5 ( substr ( $key, 0, 16 ) );
		$keyb = md5 ( substr ( $key, 16, 16 ) );
		$keyc = $ckey_length ? ($operation == 'DECODE' ? substr ( $string, 0, $ckey_length ) : substr ( md5 ( microtime () ), - $ckey_length )) : '';
		
		$cryptkey = $keya . md5 ( $keya . $keyc );
		$key_length = strlen ( $cryptkey );
		
		$string = $operation == 'DECODE' ? base64_decode ( substr ( $string, $ckey_length ) ) : sprintf ( '%010d', $expiry ? $expiry + time () : 0 ) . substr ( md5 ( $string . $keyb ), 0, 16 ) . $string;
		$string_length = strlen ( $string );
		
		$result = '';
		$box = range ( 0, 255 );
		
		$rndkey = array ();
		for($i = 0; $i <= 255; $i ++)
		{
			$rndkey [$i] = ord ( $cryptkey [$i % $key_length] );
		}
		
		for($j = $i = 0; $i < 256; $i ++)
		{
			$j = ($j + $box [$i] + $rndkey [$i]) % 256;
			$tmp = $box [$i];
			$box [$i] = $box [$j];
			$box [$j] = $tmp;
		}
		
		for($a = $j = $i = 0; $i < $string_length; $i ++)
		{
			$a = ($a + 1) % 256;
			$j = ($j + $box [$a]) % 256;
			$tmp = $box [$a];
			$box [$a] = $box [$j];
			$box [$j] = $tmp;
			$result .= chr ( ord ( $string [$i] ) ^ ($box [($box [$a] + $box [$j]) % 256]) );
		}
		
		if ($operation == 'DECODE')
		{
			if ((substr ( $result, 0, 10 ) == 0 || substr ( $result, 0, 10 ) - time () > 0) && substr ( $result, 10, 16 ) == substr ( md5 ( substr ( $result, 26 ) . $keyb ), 0, 16 ))
			{
				return substr ( $result, 26 );
			} else
			{
				return '';
			}
		} else
		{
			return $keyc . str_replace ( '=', '', base64_encode ( $result ) );
		}
	}
	function code2utf($num)
	{
		if ($num < 128)
			return chr ( $num );
		if ($num < 1024)
			return chr ( ($num >> 6) + 192 ) . chr ( ($num & 63) + 128 );
		if ($num < 32768)
			return chr ( ($num >> 12) + 224 ) . chr ( (($num >> 6) & 63) + 128 ) . chr ( ($num & 63) + 128 );
		if ($num < 2097152)
			return chr ( ($num >> 18) + 240 ) . chr ( (($num >> 12) & 63) + 128 ) . chr ( (($num >> 6) & 63) + 128 ) . chr ( ($num & 63) + 128 );
		return '';
	}
	function unescape($strIn, $iconv_to = 'UTF-8')
	{
		$strOut = '';
		$iPos = 0;
		$len = strlen ( $strIn );
		while ( $iPos < $len )
		{
			$charAt = substr ( $strIn, $iPos, 1 );
			if ($charAt == '\\')
			{
				$iPos ++;
				$charAt = substr ( $strIn, $iPos, 1 );
				if ($charAt == 'u')
				{
					// Unicode character
					$iPos ++;
					$unicodeHexVal = substr ( $strIn, $iPos, 4 );
					$unicode = hexdec ( $unicodeHexVal );
					$strOut .= self::code2utf ( $unicode );
					$iPos += 4;
				} else
				{
					// Escaped ascii character
					$hexVal = substr ( $strIn, $iPos, 2 );
					if (hexdec ( $hexVal ) > 127)
					{
						// Convert to Unicode
						$strOut .= self::code2utf ( hexdec ( $hexVal ) );
					} else
					{
						$strOut .= chr ( hexdec ( $hexVal ) );
					}
					$iPos += 2;
				}
			} else
			{
				$strOut .= $charAt;
				$iPos ++;
			}
		}
		if ($iconv_to != "UTF-8")
		{
			$strOut = iconv ( "UTF-8", $iconv_to, $strOut );
		}
		return $strOut;
	}
	
	/**
	 * $str 原始字符串
	 * $encoding 原始字符串的编码，默认GBK
	 * $prefix 编码后的前缀，默认"&#"
	 * $postfix 编码后的后缀，默认";"
	 */
	function enunicode($str, $encoding = 'GBK', $prefix = '&#', $postfix = ';') {
		$str = iconv($encoding, 'UCS-2', $str);
		$arrstr = str_split($str, 2);
		$unistr = '';
		for($i = 0, $len = count($arrstr); $i < $len; $i++) {
			$dec = hexdec(bin2hex($arrstr[$i]));
			$unistr .= $prefix . $dec . $postfix;
		}
		return $unistr;
	}
	
	/**
	 * $str Unicode编码后的字符串
	 * $encoding 原始字符串的编码，默认GBK
	 * $prefix 编码字符串的前缀，默认"&#"
	 * $postfix 编码字符串的后缀，默认";"
	 */
	function deunicode($unistr, $encoding = 'GBK', $prefix = '&#', $postfix = ';') {
		$arruni = explode($prefix, $unistr);
		$unistr = '';
		for($i = 1, $len = count($arruni); $i < $len; $i++) {
			if (strlen($postfix) > 0) {
				$arruni[$i] = substr($arruni[$i], 0, strlen($arruni[$i]) - strlen($postfix));
			}
			$temp = intval($arruni[$i]);
			$unistr .= ($temp < 256) ? chr(0) . chr($temp) : chr($temp / 256) . chr($temp % 256);
		}
		return iconv('UCS-2', $encoding, $unistr);
	}
	
}
?>